package main

import (
	"fmt"
	"sync"
	"time"
)

type Count struct {
	sum         int       //记录当前区间的计数
	currentTime time.Time //记录当前区间开始的时间
}
type Counter struct {
	count       []*Count //总的队列
	index       int      //记录当前的位置
	span        int      // 区间大小 默认 200 ms
	sec         int      //统计区间 默认一秒
	windowsSize int      //窗口大小 默认5
	mutex       sync.Mutex
}

func NewCounter(sec int, span int) *Counter {
	windowsSize := sec * 1000 / span
	size := windowsSize*2 + 1
	c := &Counter{
		count:       make([]*Count, size),
		index:       0,
		span:        span,
		sec:         sec,
		windowsSize: windowsSize,
		mutex:       sync.Mutex{},
	}
	for i := 0; i < len(c.count); i++ {
		c.count[i] = &Count{
			sum:         0,
			currentTime: time.UnixMilli(0),
		}
	}
	return c
}

func (c *Counter) add() {
	now := time.Now()
	c.mutex.Lock()
	defer c.mutex.Unlock()

	if now.Sub(c.count[c.index].currentTime).Milliseconds() > int64(c.span) {
		c.index++
		if c.index >= len(c.count) {
			c.index = 0
		}
	}
	if now.Sub(c.count[c.index].currentTime).Seconds() > float64(c.sec) {
		c.count[c.index].sum = 0
		c.count[c.index].currentTime = time.Now()
	}
	c.count[c.index].sum++
}
func (c *Counter) get() int {
	currentIndex := c.index
	sum := 0
	c.mutex.Lock()
	defer c.mutex.Unlock()
	now := time.Now()
	for i := c.windowsSize; i > 1; i-- {
		if now.Sub(c.count[currentIndex].currentTime).Seconds() > float64(c.sec) {
			break
		}
		sum += c.count[currentIndex].sum
		currentIndex--
		if currentIndex < 0 {
			currentIndex = len(c.count) - 1
		}
	}
	return sum
}
func main() {
	counter := NewCounter(1, 200)
	for i := 0; i < 10000; i++ {
		fmt.Println(i, "-------")
		counter.add()
		time.Sleep(time.Microsecond * 200)
		sum := counter.get()
		fmt.Println(sum)
		fmt.Println("---------")
	}
}
